Skip to content

refactor: currency code validation and helpers - #4757

Merged
chrisgacsal merged 6 commits into
mainfrom
refactor/currencyx
Jul 21, 2026
Merged

refactor: currency code validation and helpers#4757
chrisgacsal merged 6 commits into
mainfrom
refactor/currencyx

Conversation

@chrisgacsal

@chrisgacsal chrisgacsal commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • centralize fiat and custom currency-code validation in shared helpers
  • allow currencyx.Code to represent and validate both fiat and custom currency codes
  • implement models.Equaler[Code] with exact, case-sensitive equality
  • expose Code.Type() to classify three-character fiat codes and custom currency codes

Impact

Callers can use currencyx.Code consistently for fiat and custom currencies, compare codes through the standard models.Equaler contract, and determine the currency type without constructing a full currency value.

Validation

  • go vet ./pkg/currencyx/...
  • go test ./pkg/currencyx/...

Summary by CodeRabbit

  • New Features
    • Added exported custom currency-code length bounds and improved currency-code equality/type classification.
    • Strengthened custom currency-code validation (rejects empty/whitespace/|, enforces length bounds, and blocks fiat-recognized values).
  • Bug Fixes
    • Improved validation consistency across fiat/custom currency creation and validation.
    • Updated balance and input validation to use centralized currency validation; non-fiat currencies are now rejected with a clear invalid-currency reason.
  • Tests
    • Added unit tests for currency-code validation, equality, type detection, and centralized currency validation behavior.

Greptile Summary

This PR centralizes currency-code behavior and keeps ledger accounting limited to fiat currencies. The main changes are:

  • Shared validation for fiat and custom currency codes.
  • Exact, case-sensitive code equality and currency-type helpers.
  • Fiat-only validation for ledger balance operations.
  • Updated generated billing equality helpers and focused tests.

Confidence Score: 5/5

This looks safe to merge.

  • Currency validity is checked before the ledger applies its fiat-only restriction.
  • The new equality method preserves the previous exact string comparison.
  • No blocking issue remains in the updated code.

Important Files Changed

Filename Overview
pkg/currencyx/code.go Adds shared code validation, exact equality, and fiat/custom classification helpers.
pkg/currencyx/currency.go Reuses the shared helpers when validating and constructing currency values.
openmeter/ledger/routing.go Rejects custom currency codes after validating the general code format.
openmeter/ledger/customerbalance/facade.go Applies ledger-specific currency validation to explicit balance queries.
openmeter/ledger/customerbalance/service.go Applies the fiat-only ledger contract during service input validation.
openmeter/billing/derived.gen.go Uses the new exact code equality method in generated billing comparisons.
openmeter/billing/models/stddetailedline/derived.gen.go Uses the new exact code equality method for detailed billing lines.

Reviews (3): Last reviewed commit: "fix: reject custom currencies in ledger ..." | Re-trigger Greptile

Context used (3)

  • Context used - CLAUDE.md (source)
  • Context used - AGENTS.md (source)
  • Context used - api/spec/AGENTS.md (source)

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

currencyx.Code now validates fiat and custom currency codes directly, exposes equality and type classification, and implements validation interfaces. Currency models and ledger validation reuse these rules, while billing equality checks use Currency.Equal.

Changes

Currency code validation

Layer / File(s) Summary
Code contracts and validation
pkg/currencyx/code.go, pkg/currencyx/code_test.go
Code adds equality and fiat/custom classification, validates category-specific rules with aggregated errors, and gains interface assertions. Tests cover validation, equality, and type behavior.
Currency model integration
pkg/currencyx/currency.go
Fiat and custom currency validation delegate to shared code validators, and fiat construction validates codes before definition lookup. Custom code length constants move to code.go.
Ledger currency gating
openmeter/ledger/routing.go, openmeter/ledger/routing_test.go, openmeter/ledger/customerbalance/...
Ledger validation rejects custom currencies, customer-balance validation uses ledger.ValidateCurrency, and related tests use invalid route-delimited input.
Billing equality updates
openmeter/billing/derived.gen.go, openmeter/billing/models/stddetailedline/derived.gen.go
Generated equality predicates compare currency values through Currency.Equal instead of direct equality.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: release-note/bug-fix

Suggested reviewers: turip, galexihu, mark-vass-konghq

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: refactoring currency code validation into shared helpers.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/currencyx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chrisgacsal chrisgacsal self-assigned this Jul 21, 2026
@chrisgacsal chrisgacsal added the release-note/ignore Ignore this change when generating release notes label Jul 21, 2026
@chrisgacsal
chrisgacsal requested a review from turip July 21, 2026 08:34
@chrisgacsal
chrisgacsal marked this pull request as ready for review July 21, 2026 08:35
@chrisgacsal
chrisgacsal requested a review from a team as a code owner July 21, 2026 08:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
pkg/currencyx/currency.go (1)

289-294: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use an else branch for better readability.

For cleaner control flow and to mirror the FiatCurrency.Validate() structure just above it, consider combining these consecutive if checks into an if-else block.

♻️ Proposed refactor
 	if c.def == nil {
 		errs = append(errs, errors.New("currency is not initialized"))
-	}
-
-	if c.def != nil {
+	} else {
 		if err := validateCustomCurrencyCode(Code(c.def.ISOCode)); err != nil {
 			errs = append(errs, err)
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/currencyx/currency.go` around lines 289 - 294, Update the validation
logic in the currency validation method around c.def so the existing c.def !=
nil check becomes the else branch of the c.def == nil condition. Preserve both
existing behaviors: report the uninitialized-currency error when c.def is nil,
otherwise validate the custom currency code.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/currencyx/currency.go`:
- Around line 289-294: Update the validation logic in the currency validation
method around c.def so the existing c.def != nil check becomes the else branch
of the c.def == nil condition. Preserve both existing behaviors: report the
uninitialized-currency error when c.def is nil, otherwise validate the custom
currency code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2fec9e5f-fc42-4416-90f6-b016e898a59c

📥 Commits

Reviewing files that changed from the base of the PR and between 8732d86 and 32f573d.

📒 Files selected for processing (3)
  • pkg/currencyx/code.go
  • pkg/currencyx/code_test.go
  • pkg/currencyx/currency.go

currencyx.Code now accepts valid custom currency codes, but ledger accounting remains fiat-only because amount precision and booking semantics depend on fiat definitions.

Centralize the boundary in ledger.ValidateCurrency and reuse it from customer balance validation so custom codes fail early with ErrCurrencyInvalid while malformed codes retain their existing validation behavior. Add coverage for valid fiat, invalid, and unsupported custom currency codes.
@chrisgacsal
chrisgacsal requested a review from GAlexIHU July 21, 2026 09:20
@chrisgacsal chrisgacsal added release-note/misc Miscellaneous changes and removed release-note/ignore Ignore this change when generating release notes labels Jul 21, 2026
@chrisgacsal
chrisgacsal enabled auto-merge (squash) July 21, 2026 09:26
@chrisgacsal
chrisgacsal merged commit f16570f into main Jul 21, 2026
27 of 29 checks passed
@chrisgacsal
chrisgacsal deleted the refactor/currencyx branch July 21, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/misc Miscellaneous changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants